package com.fzy.common.queue.worker;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.concurrent.*;


public class RubbishProducer {

    private static Logger logger = LoggerFactory.getLogger(RubbishProducer.class);

    private RubbishProducer() {
    }

    private static class InnerRubbishProducer {
        static RubbishProducer instance = new RubbishProducer();
    }

    public static RubbishProducer getInstance() {
        return InnerRubbishProducer.instance;
    }

    // 1 维护盛放任务的容器，无边界非阻塞队列，任务可以无限制的往里面加入
    private static ConcurrentLinkedQueue<Task> taskQueue = new ConcurrentLinkedQueue<>();

    // 2 维护一个拥有100个消费者线程的阻塞队列的线程执行者
    private static ExecutorService executorService = null;

    // 3 初始化线程执行者，因为是生产者是单例模式，所以，线程执行者值初始化一次
    public void createExecuterService() {
        if (executorService == null) {
            int corePoolSize = Runtime.getRuntime().availableProcessors() * 2;
            executorService = new ThreadPoolExecutor(corePoolSize, corePoolSize, 10L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(50));
            logger.info("[生产者线程]创建线程执行者，corePoolSize：{}", corePoolSize);
        }
    }

    // 4.1 需要一个提交任务的方法，将任务和消费者解耦，仅仅是一个任务通道
    public void submit(Task task) {
        taskQueue.add(task);
    }

    // 4.2 重载一个提交任务的方法
    public void submit(List<Task> tasks) {
        taskQueue.addAll(tasks);
    }

    // 5 设置消费者的任务队列，执行消费者，但不需要消费者返回值
    public void execute(Worker worker) {
        worker.setTaskQueue(taskQueue);
        executorService.execute(worker);
    }

}
